Children – Needing Manual Arranging #child #family #sortdate

After running the query Children-SetOrderByBirthSortDate.sql, there may remain families that need to be manually arranged because one or more of the children has no birth-type fact or has a dominant birth-type fact with no date. This query produces a list of the parents who have such children. Look up and select one of the parents in the Sidebar Index with Family as the Main View and edit as needed.

This query also returns families with a single child; it is helpful in TimeLine and other views and reports to have at least an estimated date of Birth, even just a sort date.

Children-NeedingManualArranging-2.sql

2015-01-23 1st release
2015-01-24 rev to show count of children in family
2015-01-24 rev2 to make standalone, using the WITH syntax with Common Table Expressions for brevity

Discussions & comments from Wikispaces site


thejerrybryan

Bug?

thejerrybryan
19 August 2016 14:16:54

There seems to be something wrong with the script. It begins with WITH statement instead of with a SELECT statement. It may be a valid construction, but if so then I’m not familiar with it. And any case, it fails when run with SQLiteSpy.

Jerry


thejerrybryan

thejerrybryan
19 August 2016 14:19:11

Oops, I see that rev2 changed it to use the WITH syntax with which I’m not familiar. So I guess the syntax is valid. But it doesn’t seem to work with SQLiteSpy.

Set Living Flag #update #living

Superseded 2015-01-25. See Living Flag – Set Globally.

Discussion in RootsMagic-Users pointed out some limitations with the Set Living tool in RootsMagic and the risk of unsetting persons that have been previously set correctly. This page discusses how SQLite might help and is intended to start the development of some useful queries.

The Living flag is stored in the PersonTable in the column named ‘Living’. It has two values: 1=True (Alive), 0=False (Dead).

This query can set all persons to the same state:

UPDATE PersonTable
 SET Living=0; -- Dead 0, Living 1

This query can find all persons with a Death fact:

     -- Persons with death facts
     SELECT PersonID FROM PersonTable, EventTable
      WHERE PersonID=OwnerID
      AND EventType=2;

This query can find all persons with an Individual fact (excluding Family facts) before a given year (1906, in this example):

     -- Persons with any Individual facts dated earlier than 1906
     SELECT PersonID FROM PersonTable, EventTable
      WHERE PersonID=OwnerID
      AND OwnerType=0
      AND DATE LIKE 'D%'
      AND substr(DATE,4,4)<'1906';

We can combine these into one query that will set the Living flag to False for persons with a Death fact or having an individual fact dated earlier than 1906:

UPDATE PersonTable
 SET Living=0 -- Dead 0, Living 1
 WHERE PersonID
 IN (
     -- Persons with death facts
     SELECT PersonID FROM PersonTable, EventTable
      WHERE PersonID=OwnerID
      AND EventType=2
     UNION
     -- Persons with any Individual facts dated earlier than 1906
     SELECT PersonID FROM PersonTable, EventTable
      WHERE PersonID=OwnerID
      AND OwnerType=0
      AND DATE LIKE 'D%'
      AND substr(DATE,4,4)<'1906'
     )
;

This query can be extended to include Family facts (Marriage, Divorce, etc.) older than the given year. We’ll leave that to later or for someone else to add.

So that’s all well and good but for a lot of ancestors, there may be no events, let alone dates. If no Death fact has been entered, then the above queries will leave the Living flag alone; if it was set to True, that’s the way it will stay. It would be great, therefore, to set the Living flag to false for all ancestors and children of some person whose events occurred before the trigger year of, say, 1906. This is probably not readily done within SQLite because it requires a recursion routine through PersonTable and FamilyTable. It can readily be done in a high level programming language that calls SQLite and operates on the results with additional calls. You can see the problem of doing what is essentially the Pedigree tree by examining this 5-generation paternal line query:

SELECT P1.PersonID||','||P1.FatherID||ifnull(','||P2.FatherID,'')||ifnull(','||P3.FatherID,'')||ifnull(','||P4.FatherID,'') AS Pedigree
FROM
(SELECT P.PersonID, F.FatherID FROM PersonTable P , FamilyTable F
 INNER JOIN PersonTable H ON(F.FatherID=H.PersonID)
 WHERE P.ParentID=F.FamilyID) AS P1
LEFT JOIN
(SELECT P.PersonID, F.FatherID FROM PersonTable P , FamilyTable F
 INNER JOIN PersonTable H ON(F.FatherID=H.PersonID)
 WHERE P.ParentID=F.FamilyID) AS P2
ON (P1.FatherID=P2.PersonID)
LEFT JOIN
(SELECT P.PersonID, F.FatherID FROM PersonTable P , FamilyTable F
 INNER JOIN PersonTable H ON(F.FatherID=H.PersonID)
 WHERE P.ParentID=F.FamilyID) AS P3
ON (P2.FatherID=P3.PersonID)
LEFT JOIN
(SELECT P.PersonID, F.FatherID FROM PersonTable P , FamilyTable F
 INNER JOIN PersonTable H ON(F.FatherID=H.PersonID)
 WHERE P.ParentID=F.FamilyID) AS P4
ON (P3.FatherID=P4.PersonID)
;

It produces results like this:

Pedigree
1,116
4,7
5,7
6,254,155,829,138
8,829,138,821
11,829,138,821

A starting person’s RIN is on the left, father next to the right, grandfather next, etc. Results could be constrained to those first persons having old event dates and an UPDATE of the Living flag to 0 for each PersonID (RIN) in that person’s list of paternal parents. However, we would need to grow the query with another LEFT JOIN for each additional generation, hence the need for a recursive routine that would re-use the same core query for each generation until the last ancestor was found. And this was just the paternal line – to add the maternal line and each set of grandparents at each generation is unwieldy without recursion.

If someone can find a way to recurse using SQLite, that would be great; otherwise, some high-level programming is required.
[inline comment: “find a way to recurse using SQLite”

external image user_none_lg.jpg ve3meo Apr 13, 2014

It is now possible: Ancestors+Query+-+Recursive

]

Discussions & comments from Wikispaces site


thejerrybryan

Recursive Query

thejerrybryan
04 July 2011 02:23:38

I have been away from the computer most of the day, but prior to that I had already completed a series of queries that are very similar to the ones you you just posted. I was planning to post them when I got back on the computer tonight. I’ll try to get mine posted as soon as I can, just as a way to compare notes.

I don’t know of any way to do the kind of recursion with SQL that would be required to do something to “all ancestors”, but my update to “set parents of those born before 1906 to not living” can be run multiple times, and each time it would pick up at least one new generation. So we can sort of fake out a recursion simply by running the same update a bunch of times.

It will probably be tomorrow before I get anything else posted.

Jerry


ve3meo

ve3meo
14 April 2014 02:34:12

Have a look at Ancestors+Query+-+Recursive

Tom

Inline comments


ve3meo

Comment: It is now possible: http://sqlitetool…

ve3meo
14 April 2014 02:40:35

It is now possible: Ancestors+Query+-+Recursive

Another version of a Set Living query #living

Superseded 2015-01-25. See Living Flag – Set Globally.


I’m posting my version of SQL for Set Living. It proves to be remarkably similar to Tom’s.

SQL #1, we turn on the Living Flag for everybody in the database. Essentially, we make everybody private and then followup later by setting individuals as not private when they don’t need to be.

--                             Start by privatizing everyone in the database
 
UPDATE PersonTable
  SET Living = 1     -- 0 is not living, 1 is living
  WHERE Living != 1  -- In case it's faster not to update the ones that are already set to living
;

This code differs from Tom’s in that it includes the WHERE Living != 1 clause. The idea is to improve performance slightly by only setting to 1 those flags that are not already 1. In most programming contexts, this would be a silly distinction to make. In a procedural language such as C/C++, I would never consider code such as if (x != 1) x = 1 when a simple x = 1 would do, and indeed the simple form would run faster. But disks are vastly slower than main computer memory and it seems to me that avoiding the write operation associated with SET LIVING = 1 whenever possible might improve performance. But this case the UPDATE runs so quickly either way that I can’t prove which is faster. However, in later queries in this sequence it turns out that it’s important to keep the number of rows being operated on as small as possible, not so much for performance reasons as for other reasons.

SQL #2, we turn off the Living Flag for everyone whose birth date is before 1906.

--                             Unprivatize everyone born before 1906
 
UPDATE PersonTable
  SET Living = 0
  WHERE PersonID IN
    (
     SELECT P.PersonID
       FROM PersonTable AS P
              INNER JOIN
            NameTable AS N ON ( (P.PersonID = N.OwnerID) AND (N.NameType = 0) )  -- Use only the primary name table entry
       WHERE N.BirthYear > 0     --  BirthYear Exists
                AND
             N.BirthYear < 1906
    )
;

This is a case where I like Tom’s code much better than mine. Mine uses the birth year from the NameTable, which is not as reliable as using the EventTable as does Tom. Also, mine only uses the birth date, whereas Tom’s code uses any fact date from the EventTable. So his code is going to detect more people who should have the Living Flag turned off than mine. I had intended my code as a quick and dirty proof of concept, and I had intended to go back and reference the EventTable later with my final code. In looking Tom’s code to fully interpret dates, it seemed more complicated than I wanted to deal with until I had completed my proof of concept. But Tom already wrote very simple code to interpret dates as needed by this query.

However, Tom’s code at this point also includes turning off the the Living Flag for every individual who has a Death Fact, irrespective of what date (if any) is associated with the Death Fact. That’s an important item to accomplish, but my overall process requires that it be left until last.

SQL #3, we turn off the Living Flag for the parents of everyone whose Living Flag has already been turned off. It’s essential at this point in the process that the only reason the Living Flag has been turned off for anybody is because they have an Event Date (any event) prior to 1906. The parents of any such individuals are guaranteed to be deceased. But if the Living Flag is turned off for somebody because they have a Death Fact and the Death Date is 2007, then there is no guarantee that the parents are deceased.

--                             Unprivatize parents of everyone who is already unprivatized
 
UPDATE PersonTable
  SET Living = 0
  WHERE PersonID IN
    (
          SELECT PP.PersonID
            FROM PersonTable AS P
                   INNER JOIN
                 FamilyTable AS F ON (F.FamilyID = P.ParentID)
                   INNER JOIN
                 PersonTable AS PP ON (F.FatherID = PP.PersonID)
           WHERE ( (P.Living = 0) AND (PP.Living = 1) )
 
          UNION
 
          SELECT PP.PersonID
            FROM PersonTable AS P
                   INNER JOIN
                 FamilyTable AS F ON (F.FamilyID = P.ParentID)
                   INNER JOIN
                 PersonTable AS PP ON (F.MotherID = PP.PersonID)
           WHERE ( (P.Living = 0) AND (PP.Living = 1) )
    )
;

A UNION is required to get both the father and the mother. But once you figure out how to do the father, you just clone the father code to make it into the mother code and combine the two with UNION.

It took me a long time to figure out how to do this UPDATE. The primary conceptual problem was understanding how to reference both the PersonTable.PersonID of the person and the PersonTable.PersonID of the parents in the same sub-query, and then how to pass the correct PersonID out of the sub-query back to the query on the outside of the sub-query. In retrospect, it seems obvious and simple. But before I figured it out, it seemed almost impossible. I plan to post a separate "lessons learned" page about just that issue.

Note that contrary to intuition, SQL #3 doesn’t need to look at any dates whatsoever because the heavy lifting on dates has already been completed in SQL #2. And if I were to change SQL #2 to look at the dates of all fact types as in Tom’s code, I still would not need to change SQL #3 at all.

As Tom pointed out, the problem at this point is that you really need to run a recursion on this query, and to run the recursion enough labels deep to get all the ancestors, not just the parents. I can’t think of any way to accomplish such a recursion within a single UPDATE. But SQL #3 can be run as many times as you wish, and each time it is run it will get one additional generation of ancestors. But how many times should you run it? To that end, we can do the following.

SQL #4, for which individuals (or for how many) could we turn off the Living Flag if we ran SQL #3 again.

SELECT Z.PersonID           -- or SELECT COUNT(Z.PersonID)
  FROM
    (
          SELECT PP.PersonID
            FROM PersonTable AS P
                   INNER JOIN
                 FamilyTable AS F ON (F.FamilyID = P.ParentID)
                   INNER JOIN
                 PersonTable AS PP ON (F.FatherID = PP.PersonID)
           WHERE ( (P.Living = 0) AND (PP.Living = 1) )
 
          UNION
 
          SELECT PP.PersonID
            FROM PersonTable AS P
                   INNER JOIN
                 FamilyTable AS F ON (F.FamilyID = P.ParentID)
                   INNER JOIN
                 PersonTable AS PP ON (F.MotherID = PP.PersonID)
           WHERE ( (P.Living = 0) AND (PP.Living = 1) )
    ) AS Z
;

So we can run SQL #3 and SQL #4, followed by SQL #3 and SQL #4, over and over again until SQL #4 yields no rows. At that point, SQL #3 will have done all it can do and we can proceed to SQL #5.

For this query, P.Living in the sub-query is the Living Flag for the individual, and PP.Living in the sub-query is the Living Flag for the parent of the individual. The WHERE statement is coded as WHERE ( (P.Living = 0) AND (PP.Living = 1) ), which tests for situations where the individual is not living but the parent is still flagged as living. And remember that the not living condition at this point is strictly due to event dates, not yet on the presence of a death fact. So it would be sufficient to code the WHERE simply as WHERE P.Living = 0 in the SQL #3. But writing the WHERE statement as it was written is more efficient than just testing for P.Living because it keeps the number of rows in the sub-query as small as possible. And more importantly, SQL #4 will not produce the correct results without testing both P.Living and PP.Living.

SQL #5, turn off the Living Flag for all individuals who have a death fact. It is now safe to do so because we have done everything we can do with ancestors.

--                             Unprivatize everyone with a valid death date
--
--   We separate the processing of the death year from the processing of the birth year because
--   we need to process ancestors before we unprivatize based on the existence of a death date
 
UPDATE PersonTable
  SET Living = 0
  WHERE PersonID IN
    (
     SELECT P.PersonID
       FROM PersonTable AS P
              INNER JOIN
            NameTable AS N ON ( (P.PersonID = N.OwnerID) AND (N.NameType = 0) )  -- Use only the primary name table entry
       WHERE
         N.DeathYear > 0         -- Death year exists, doesn't matter what it is if it exists
     )
;

My code tests for the presence of a death date, whereas Tom’s code tests for the presence of a death fact. Tom’s code is complete and mine is not. I need to change mine to match Tom’s.

Jerry

Discussions & comments from Wikispaces site


ve3meo

Comment: “…really need to run a recursion on this query…”

ve3meo
03 September 2018 19:43:31

ve3meo Apr 13, 2014

Maybe there is now a way: Ancestors+Query+-+Recursive

Living Flag – Set Globally #living #update #recursive

Finally! A script that sets the Living flag globally without having to be run repeatedly until all ancestors are accounted for. It does so with the recursive query feature introduced in SQLite3 in 2014 (see the page Recursive Queries – Ancestors and Descendants for more background). This script supersedes prior efforts by Tom and Jerry, respectively:
Set Living Flag
Another version of a Set Living query

It is simple enough to set the Living flag to false when a person has a Death fact. The previous scripts went further than that, e.g., deeming a person to be dead if their Birth was more than 105 years ago, as is the case with RootsMagic. Where they came to a halt or grinding reiteration was the need to deem dead all ancestors of all such persons deemed dead.

This new script expands on the deemed dead criteria and utilises a variant of the recursive query referenced above to cover all their ancestors. Here is an outline of the expanded criteria for setting the Living flag to False (for dead):
1. person with individual or family events before current year less 105, e.g., 1910 in 2015;
2. person whose spouse has individual events before this cusp year;
3. children of persons with birth before a certain year or death before a later year should be deemed dead (if person born >105 yrs ago deemed dead, then
a) child of parent born > (105 + 25) yrs ago could be deemed to have been born around 105 years ago and now dead
b) child of parent who died > 105 years ago can be deemed to have been born around the same time and now dead;
4. spouses of persons deemed dead are probably also dead;
(arguably a bit risky but, without it, many ancient spouses can be left Living)
5. ancestors of all the above persons;
6. person with death fact;

For everyone else, the script sets the Living flag to true.

From initial testing, the results look pretty reliable. I think there could be isolated instances of a person deemed living when they should be dead. For example, any person with more than 3 generations of descendants, none of which have any dated events or a Death fact – a pretty unlikely scenario. That said, it is desirable for many other reasons that an estimated era for Birth and Death should be entered and that would also resolve this issue.

A complementary script sets color coding to Red for Living flag true and to Green for Living flag false.

Both scripts should run on any SQLite3 manager compiled with SQLite 3.8.3 or later.

LivingFlag-GlobalSet.sql
ColorCode-byLivingFlag.sql
2015-01-25 1st release

SQLiteManagers #sqlitemanagers

SQLite Management Tools : a comprehensive table for multiple operating systems but not updated since 2011.
The following table describes a few tried by one member of this wiki. The page SQLite Managers for Mac OS looks into some for the Mac.

WinMacProductReviewRating
TomH
YNSQLite Expert PersonalFree subset of the $59 Professional version. Excellent results display, sort, filter, thumbnails of images. BLOB viewer/editor. Copy/paste for results export. Save/load SQL files. Supports loadable extensions including most compatible fake RMNOCASE. Supports runtime parameters. Best at handling very large databases, large result sets and multiple open databases. Very frequently updated.
2021-07-18: current version is 5.3
8.8
YNSQLiteSpy

alternative SQLite Spy download link

Free, basic, clean manager capable of bypassing the RMNOCASE obstruction by using a fake collation. Fastest display of table data; sort by column with both numerical and ASCII fields. Export results by copy to clipboard and paste to Excel or text editor. Export/Import SQL. Frequently updated. 1.9.0 supports loadable extensions with potential for RM date processing and other lengthy expressions to be made custom functions. Can bog down on very large intermediate or final results sets.
2021-07-18:: version 1.9.15 released 8 Feb 2021
8.5
YNSQLite DeveloperWere it not for its $29 license, this one would tie or be first. Only one to have choice of user named UniCode collations, hence a substitute for RMNOCASE and no more COLLATE NOCASE overrides. Has good sorting (no numerical sort), filtering, bookmarking and exporting of results. Export/import SQL files. SQL structured formatting. NB: the free Lite version lacks the Collation and some other tools. Good support for bug fixes.
2021-07-18: latest release was 4.2 in 2016
8
YYSQLitemanSimple, reliable but no visual query builder. Good error handling. Can export and import SQL files and save SQL Views. Development appears to have stalled in 2010.
2021-07-18 new website; $1/mo subscription model “native UI” apps for Windows 10 and macOS.
6
YNDBTools DBManager StandardMore professional, commercial. Seems complex and powerful but freeware version out-dated (2007) and restricted.
2021-07-18 no further development since 2007
6
YNSQLite2009 ProAttractive GUI. Fast visual query builder. Unreliable – crashed on some queries or views with poor error handling (Jan 2010). Version 3.7.6.3 as of 2011-05-20 still does not save or load a SQL file – must copy to/from clipboard; takes almost twice as long as SQLiteSpy to execute LifeLines-OO.sql on a large database (117MB). Current 3.8.3.1 (2014-02) has not been tested.
2021-07-18 website uninformative; Software Informer shows latest version as 3.8.3.1 released in 2016
5
YYSQLiteStudioVersion 3 (2014-12) under review; promising.
2021-07-18: current version is 3.3.3
7?
YNSQLite AdministratorBeta. Quirky column widths in results display. No sorting, filtering. No import/export of queries or data. Queries saved to db table. Not updated since 0.8.3.2 (2006).
2021-07-18 unchanged
3
YYDB Browser for SQLiteVery limited. A basic browser. (that is an old review…)
2021-07-18 current v.3.12.2 for Windows & macOS released 2021-05-18
3?

I tend to use a combination of SQLite Expert Personal and SQLiteSpy when developing new queries. For using established queries, I rather prefer the look of the results tables from Spy but Expert handles user inputted parameters at run-time. For a new user, Spy is probably the easier of the two to start with. SQLite Expert Personal is better for its performance on very large databases, display of JPG blobs and the availability of a highly compatible substitute RMNOCASE collation.

Discussions & comments from Wikispaces site


ve3meo

Speed Reporting Complicated

ve3meo
14 January 2010 14:36:14

Evaluating speed has turned out to be more complicated than expected. The supposed speed regression after sqlite 3.6.17 is not exactly that. It seems that either the database design or the query design or both confuse the sqlite query optimiser into making sub-optimal choices of index files up to that version and different, worse ones after. That resulted in the necessity of using INDEXED BY and NOT INDEXED clauses to force the use of appropriate indexes, contrary to what the documentation instructs. As INDEXED was implemented with sqlite 3.6.3, older tools (SQLiteman, DBManager…) error out on the query but the later ones all execute at about the same speed (~3s).


ve3meo

ve3meo
11 March 2010 15:45:33

I should qualify these speed tests further and update them to reflect my best understanding. RM4’s NameTable has an index on the IsPrimary field. This seems to be a rather useless index because the field has only two values and thus cannot provide any speed improvement over a full scan. On the other hand, most searching of NameTable is against the OwnerID field; the corresponding index provides a tremendous speedup over a full scan. When a query uses IsPrimary as a condition in combination with a lookup of OwnerID, the query optimiser chooses the idxNamePrimary index with adverse consequences. Since the above posting, I have learned to hide the IsPrimary field from the query optimiser thus obviating the need for the INDEXED clauses and rendering the query compatible (in this respect) with the older SQLite implementations. It’s accomplished simply by prefacing the IsPrimary field with the ‘+’ operator. For example,

SELECT
Surname, Given, EventTable.Date AS BirthDate
FROM
EventTable
LEFT JOIN NameTable USING( OwnerID )
WHERE
OwnerType = 0 AND +NameTable.IsPrimary = 1
;

With the ‘+’ operator, EXPLAIN QUERY PLAN reports:
order from detail
0 0 TABLE EventTable
1 1 TABLE NameTable WITH INDEX idxNameOwnerID

Without the ‘+’ operator (or the INDEXED BY clause), it reports:
order from detail
0 0 TABLE EventTable
1 1 TABLE NameTable WITH INDEX idxNamePrimary


KenCRoy

Anyone have a preference for a free SQLite manager

KenCRoy
11 March 2010 18:13:19

Do any of you have a preference for a free SQLite Manager?

I really don’t want to spend any money until I really decide to convert to RootsMagic.

I tried SQLite Expert Personal — http://sqlite-expert-personal.software.informer.com/2.1/

but it won’t run the queries as posted on this forum.


ve3meo

ve3meo
11 March 2010 22:04:24

You can see by my ratings on this page that my rankings are:

1. SharpPlus SQLite Developer
2. SQLiteSpy
3. Tie between DBTools DBManager Standard and SQLiteman.

I would welcome others to add their ratings.

In practise, I use Developer the most because it is well-featured, robust, up-to-date (uses SQLite 3.6.22 – 23 just came out in the last couple of days), can sort and filter results on screen, etc., and may be the only one that will allow editing of all the tables. I use Spy often, because it shows results the fastest and maybe the nicest and is also pretty current (SQLite 3.6.21). Initially, my favourite was SQLiteman for easy, clean, fast with DBManager free edition as the candidate for development. Both of these are quite dated – the former no longer being actively supported and developed.

I have recently started exploring OpenOffice Base and Calc using an SQLite ODBC connection to the RootsMagic files. Using the latter is quite promising for filtering and sorting copied results and there is potential for formatted reporting, along the lines of what MarkVS id developing using MSAccess. I’m not so keen on using Base to develop complex queries as error reporting is pretty uninformative. But that may be just a reflection of being at the low end of the learning curve.

None of them are ideal and you may not want to pay the license fee for extra features. So I won’t recommend for you one over another but do advise you to avoid the ones I ranked low as I think you would waste your time trying them.

Inline comments


ve3meo

Comment: 1.9.0 supports loadable extensions wi…

ve3meo
05 June 2011 11:48:10

1.9.0 supports loadable extensions with potential for a RMNOCASE collation and RM date processing

Sources – Copy Repository Name, Address from Repository List #sources #sourcetemplates #repositories


Why?

This page is in response to the request from RootsMagic Forums member
JoopvB: Repositories from TMG. He
asked:
Anybody an idea how to kind of copy the Repository (Info) from the
address table to wherever it needs to be to be used in the source
sentence? I guess I would need to create the custom fields in the source
sentences? But some automated kind of copy for more than 3000 sources
(yeah, I am a splitter 🙂 would be super.

But his problem speaks to a larger issue: some 134 built-in source
templates have a Repository field but there is no mechanism to fill it in
sources from the sources’ Repository data
.

Wish & Workaround

A desirable enhancement to Source Template Language would be the addition of
fields that pull data from the primary Repository for a source. This may
have to function as default data unless overridden by the entry of a “local”
value in the field. Unless and until such an enhancement is developed, the
following scripts can help by batch populating certain empty fields with
data from the Repository List. They may be especially useful to those
migrating from TMG which does have such fields, [REPOSITORY] and [REPOSITORY
ADDRESS]; RootsMagic 7 direct import treats them as a simple variable and
imports them empty without looking up values in the TMG Master Repository
List.
The first script changes the names of Repository variables to match those of
the RootsMagic built-in templates. The second script populates empty
Repository-type fields in Sources from values in the RootsMagic Repository
List.

Two Steps

Harmonize Field Names

 

Source Template Field Names for Repository Information
Origin of Source TemplateNameLocationReference
RootsMagic[Repository][RepositoryLoc]
JoopvB TMG import [Repository][RepositoryInfo][RepositoryReference]
TMG Sample Project import[Repository][RepositoryAddress][RepositoryReference]

With other customizations either in the originating software or in a
RootsMagic database, there could be a variety of other aliases that mean the
same thing. Even with the built-in templates, there are some exceptions: two
instances of [RepositoryCity] with [RepositorySt]; these are unhandled.
The :Abbrev modifier is also used in two instances with [RepositoryLoc] and
will necessarily be ignored unless the user types in the “||” separator in
the State field followed by the abbreviation for the location.
So it would seem desirable to make the custom ones consistent with the most
common ones found in the built-in templates so that the script that does
copying from the Repository List to the Source need only deal with one set
of names and can do so for sources based on both built-in and custom source
templates. This next script changes the templates and master sources to use
[RepositoryLoc] instead of [RepositoryAddress] and [RepositoryInfo]. It can
be readily extended to harmonize other aliases.
Sources-UnifyAliases_RepositoryLoc.sql

Copy
Values from Repositories to Sources

The following script copies Repository data to the Sources based on this
mapping:
Repository Name (AddressTable.Name) ==> [Repository]
Repository City and State (AddressTable.City, AddressTable.State) ==>
[RepositoryLoc]
Call Number (AddressLinkTable.Details) ==> [RepositoryReference]
It currently copies only to those fields that are empty, as would be the
case for a direct import from TMG. Another version could copy regardless but
that would also “reset” all “local” values to “default” which may be
undesirable.
Sources-CopyRepositoryInfoTo.sql

SubjectAuthorRepliesViewsLast Message
What
fields from AddressTable?
ve3meo ve3meo12141Dec
16, 2014
by JoopvB JoopvB
Custom
source templates, not Free Form?
ve3meo ve3meo168Dec
11, 2014
by JoopvB JoopvB

Discussions & comments from Wikispaces site


ve3meo

Custom
source templates, not Free Form?

ve3meo
11
December 2014 17:19:46

Are these sources all using custom source templates?


JoopvB

JoopvB
11
December 2014 22:02:39

Yes, all are custom templates in TMG.
Joop


ve3meo

What
fields from AddressTable?

ve3meo
11
December 2014 17:26:50

What fields do you want from the AddressTable?
Can they be concatenated into a single field in the
SourceTemplate? Think about what you want to see in the three
sentences: Footnote, Short Footnote, Bibliography. If all are
to be the same or if only one of them is to have the Repo
info, then they can be concatenated into one field. But if you
want a subset of the needed fields in another sentence, then
there must be more than one template field. Of course, there
could be template fields corresponding to the needed
AddressTable fields which might be desirable for future data
entry and greatest flexibility at the expense of complexity.


ve3meo

ve3meo
11
December 2014 19:24:47

The TMG Sample project imported to RootsMagic has custom
source templates whose name begins with “_TMG_”. These
typically have two fields named and displayed as:
Repository and RepositoryAddress
There is another field named RepositoryReference which I
presume would be specific to the source and therefore no
value for it should be expected to be in the AddressTable.
There are many standard RM source templates with the two
fields:
[Repository] = “Repository Name”
[RepositoryLoc] = “Repository Location”
So I think the AddressTable fields for the Repository info
should be mapped to these two fields:
AddressTable.Name ==> [Repository]
AddressTable.(City, State) ==> [RepositoryAddress] (or
RepositoryLoc)
That should be sufficient to identify the Repository
uniquely in the footnote and/or bibliography and to
facilitate its lookup in a Repository List for details. It
is only when publishing that such info is needed in the
footnote or bibliography because online interaction in
RootsMagic provides it outside the sentence.
Tom

Reports – Concordances for Indexes #names #alternatenames #places #reports #msword #index

Marking for Indexing Needed for Individual Summary and Custom Reports

RootsMagic 6 does not generate in reports an Index of Names or an Index of Places for the Individual Summary report, nor for custom reports. Yet one can readily generate a batch of these reports and it would be handy to have them indexed. Even when included in a Reports > Publisher ‘Book’, they are not covered by the auto-generated Indexes process. When the report is saved to RTF, one could manually mark names and places for indexing using Microsoft Word but the effort is laborious and has to be repeated the next time the report is generated.

Automarking from a Concordance Table in Microsoft Word

The good news is that MS Word has an Automark feature to expedite indexing. One simply creates a separate MS Word document containing a two column table. The left column contains the terms to be marked for indexing and the right column contains the value under which it is to be indexed, i.e., the Index entry. This is called a Concordance Table. With the report open in MS Word, you use References > Insert Index > Automark to select the Concordance file and mark for indexing all the matching terms in the document. Then, with cursor located where the Index is to be located, Insert Index again to generate the Index.

Thanks to Charlie Hoffpauir for opening my eyes to this capability in MS Word in a discussion on the RootsMagic-Users-L on publishing a report containing everyone in a database. More on Indexing and Automarking with a concordance table at How-To Geek, including a VB Script for cleaning out the index marks if you have to redo your concordance table for that document.

Problem Creating Concordance Table using RM Custom Reports

Using a RootsMagic custom report, it is possible to create a concordance table but there are issues. The Automark search is case-sensitive; an exact match is required. I like to have surnames in upper case in reports and that is achieved for standard RootsMagic reports by checkmarking the box “Display surnames in upper case” in Tools > File Options > General. However, surnames are not affected by that setting for custom reports (another piece of unfinished business…)! Moreover, to make sub-entries for a surname common to multiple persons, let alone upper case conversion, would require operating on the custom report in a spreadsheet.

Hence, SQLite to the rescue!

A Concordance Table SQLite Query and resulting Index

Names-ConcordanceCapsQuery.png
The SQLite query produced this concordance table. Copied from SQLiteSpy straight to a new MS Word document without modification.
Names-ConcordanceCaps.png
Sample of an Index generated in MS Word by Automarking from a Concordance table generated by a SQLite query.

The Index shows no entry for Betsy ALEXANDER because that search term was not found in any of the reports; Individual Summaries were generated for a subset of the database while the Concordance table has every name, including Alternate Names in it.

A similar query could generate a concordance table of Place Names, albeit a necessarily more complicated one to handle name reversals and Place Details.

Names-ConcordanceCaps.sql Requires a SQLite manager with a RMNOCASE extension.

-- Names-ConcordanceCaps.sql
-- 2014-11-25 Tom Holden ve3meo
/*
Creates a temporary SQLite View laid out as a MS Word
Concordance Table of people's names to aid in the generation
of indexes for a collection of Individual Summary reports.
It is of the form:
SearchName              | IndexName
Annie Eliza ALEXANDER | ALEXANDER: Annie Eliza
B. F. ALEXANDER          | ALEXANDER: B. F.
Betsy ALEXANDER          | ALEXANDER: Betsy
 
The left column contains the case-sensitive search string;
the right column has the value to be outputted in the Index.
In this example, the colon will cause one ALEXANDER surname
to be printed with an indented line for each os the individuals.
 
The search surnames have been uppercased because a display
setting in RootsMagic File Options for the database causes
the standard reports to output upper case surnames; that is
what Word will search. If your reports have lower case surnames,
remove the UPPER() function from the SearchName expression.
 
Likewise, if you do not want the Index to have all-cap surnames,
remove the UPPER() function from the IndexName expression.
*/
DROP VIEW IF EXISTS NameConcordanceCaps
;
CREATE TEMP VIEW NameConcordanceCaps
AS
SELECT DISTINCT
  REPLACE
  (
   TRIM
   (
    Prefix || ' '
    || Given || ' '    || UPPER(Surname) || ' '    || Suffix
    )
    , '  ', ' '
   )
  AS SearchName
  ,
  REPLACE
  (
   TRIM
   (UPPER(CASE Surname WHEN '' THEN 'UNKNOWN' ELSE Surname END) || ': '    || Prefix || ' '    || Given || ' '    || Suffix
    )
    , '  ', ' '
   )
  AS IndexName
FROM NameTable
ORDER BY IndexName
;

A Concordance Table and Index that groups by First Name

This is a more advanced table that relies on the report having the person’s Record Number following their name so that it can include Birth Year and Death Year in the Index. It responds to a wish expressed by RootsMagic Forums member Paul1307 in the topic Sorting in Index that names be sorted by surname, first name, year(s), excluding middle names from the sort.

Names-ConcordanceCapsFirstYrsMids.PNG
Snippet of the index for an 80 page batch of Individual Summary reports, created from the Concordance Table generated from a SQLite query.

This query creates a temporary View in SQLite that does the heavy lifting of parsing Given names into First Name and Middle Names and creates the Era string from the person’s Birth and Death years; it is named “NameGivensParsed”. The second View “NameConcordanceCapsFirstYrsMids” is the Concordance Table. Click on that View to see the resulting table, select all the results, copy and paste into a new blank MS Word document. Save the document to where you can readily find it for use with RM reports from this database.
Names-ConcordanceCapsFirstYrsMids.sql

RootsMagic 7

RootsMagic 7 was released on 25 Nov 2014. It will take some time to answer the following questions:

  1. Which SQLite scripts on this wiki need to be revised? Identifying changes in the database design will trigger areas to investigate.
  2. Which ones can be retired? Requires comparing the functional capabilities of RootsMagic 7 to those of the relevant scripts.
  3. Are there new exploits needed? Depends on user feedback in various forums.

Your help in this process is needed; the size of this wiki is too much to expect one person to handle in a timely fashion.

SQLiteToolsForRootsMagic Blazes Trails

Some of the new features of RootsMagic 7 were conceived and/or pioneered on this wiki. Only the RootsMagician can say what influence it has had on product development. Some examples:

New FeatureWiki PageWiki Date
Compare FilesComparing Two RM Databases2011-12
Import ListsDepopulate but keep Customs, Places, Sources
Database – Copy Master Lists to Shell
2011-12
2014-10
Backup and Restore with MediaBackup Media with Database – RAR
Backup Media with Database – 7Zip
2011-02
2011-03
Quick GroupsNamed Group – Mark or Unmark List refresh2011-11

Okay, a couple of those might be a bit of a stretch…

Database Structure Unchanged from RM6

There have been no changes to the SQLite database structure between RootsMagic 6 and 7. The database version stored in the ConfigTable remains at “6000”. Results (or absence thereof) from the following queries (run individually) support these observations. The main database was an empty one created by RootsMagic 6; the attached one was an empty one created by RootsMagic 7.

SELECT * FROM main.sqlite_master OLD
LEFT JOIN EmptyRM7000.sqlite_master NEW USING(name)
WHERE OLD.SQL NOT LIKE NEW.SQL
ORDER BY name;
 
SELECT * FROM main.sqlite_master OLD
LEFT JOIN main.sqlite_master NEW USING(name)
WHERE OLD.SQL NOT LIKE NEW.SQL
ORDER BY name;
 
SELECT CAST(DataRec AS TEXT) FROM EmptyRM7000.ConfigTable
;

That is not to suggest that one can work on the same database with both versions with impunity. There will have been changes in how fields are used, perhaps the meanings of some values, giving rise to possible problems. However, the RootsMagician says in a private email on 26 Nov: “Yes. You should be able to switch back and forth between 6 and 7.

Discussions & comments from Wikispaces site


chiptobey

Place update query

chiptobey
27 February 2017 00:12:37

Short question:
I need a query to concatenate the place detail to the place.

Long question: I used the data clean and moved things like cemetery name to the place detail. When I went to combine like places, I found this to be the wrong course as I would have to count the record position that had place detail so I would combine places resulting on people being born in the cemetery. Bruce could fix this by displaying the details on the list of locations to be combined but that hasn’t happen yet.

I have 100’s of these places and need to get the detail info back into the place so I can see which ones need to be combined.

Can you email chiptobey1@hotmail.com as well as posting? Thanks!!


ve3meo

ve3meo
27 February 2017 00:24:08

See Places – Conversion of Place Details to Places

Fact Type – Convert Census to yyyy Census and back #facttypes #census

This page and scripts respond to a wish posted by Jerry Bryan to the RootsMagic Forum, quoted in part:

… for U.S. censuses I’m thinking of creating user defined fact types called census1790, census1800, census1810, etc. through census1940. These user defined fact types would be exact clones of the built-in census fact type. For example, there is nothing that would tie the census1790 fact type to the year 1790 except for the name of the fact type. Then I would have a script that changes all census events for the year 1790 to census1790 events for the year 1790 and so forth for each U.S. census year. Nothing would change in any report that would come out of RM.

Why would I do such a strange thing? Because then I could profitably put census events into People View. At the present time, it’s a big waste of time to try to put census events into People View because census events are effectively duplicate events and only one such duplicate can be displayed in People View. With the new scheme, I could put any particular U.S. census year into People View.

And of course, on the back end, I would want to restore each of the census1790, census1800, etc. events back to standard census events.

An example of the results from these scripts can be seen in the screenshot:

FactType - Convert Census to Year_Census.PNG
The script created custom fact types from the standard Census and Census (family) fact types by prepending any year found among all the census events in the database. It then switched each event from the standard fact type to the year-specific custom census fact type. Thus, the People View can have one or more of these yyyy-Census events in columns, four chosen for this screenshot. With multiple yyyy Census columns, holes in the census pattern and migration can be easily seen.

Note that People View shows Fact or Event data for only the Principal of an Individual (Personal) fact type; Family type events are not shown nor are events for persons that are ‘sharers’, i.e., having a role other than Principal.

The scripts make no distinction among census jurisdictions; a database with many countries may have the 1901 Census fact type for UK, Canada, etc. I thought of attempting to incorporate the Country in the name of the fact type but this is impractical given the variety of Place name practices among users and the range of jurisdictions.

Requires a SQLite Manager with an extension for a RMNOCASE collation sequence.

Usage:

1. Execute once and once only if you intend this to be a temporary change.

2. To revert said temporary change to the original, one or more tables is stored in the database, named, e.g., “xCensusTypeTranspose”; you then select and execute the script in comments at the end of the script file and the special table(s) is dropped from the database after the events (and roles) have been restored to standard type.

3. If, after step 1, you add more standard events and re-execute, the reversion script can only return to the state prior to the last conversion. Only those yyyy-Census fact types that become unused through reversion will be deleted.*

4. A separate reversion script may be developed to convert all events of fact type name like “yyyy Census%” to standard Census types.

Two versions of scripts were developed. One covers both shared and unshared census events; the other can be used on a database having no shared census events and will take less time, notably on large databases.

FactType – Convert Census_shared to Year_Census.sql Use this script if you have shared Census events.
FactType – Convert Census_unshared to Year_Census.sql Use this script if you have only unshared Census events.

  • If People View has a column for a fact type that has been deleted, the next time you customize that view and exit from it, RootsMagic will appear to stall and, after a wait, throw an error message indicating that an index is out of bounds. To clear that problem, open “Customize this view” and select and Remove the blank row(s) at the bottom of the panel “Columns to display”. OK the customization and the error should be cleared.

Places to Place Details Conversion #places #placedetails #update

Why?

Splitting Places into Place and Place Details is an onerous job in RootsMagic: you have to edit every fact/event that used the original Place. Until RootsMagic comes up with a utility to make it easier to do, we need a better way. With some judicious SQLite queries and editing of RM’s Place List, there is a faster, better way. The opposite direction is much easier.

Split Place into Place and Place Detail

Here’s an example of how SQLite can carry out the bulk conversion of Places having too detailed data to Place Details of another Master Place, e.g.:
Place: Mount Pleasant Cemetery, London, Ont.
to
Place: London, Middlesex Co., Ontario, Canada
Place Detail: Mount Pleasant Cemetery
and accordingly revise the 5, 50, 500 facts/events that used the original Place or any other Place having “London, Ont” in its name.

The example uses a series of SQLite queries run one at a time in sequence, but, first, make sure that you have your desired master Place in your Place List, e.g., “London, Middlesex Co., Ontario, Canada” and MAKE A BACKUP:

-- Pick out the PlaceID of the desired Master Place, i.e., "London, Middlesex Co., Ontario, Canada",
-- from the results of this query
 
SELECT * FROM PlaceTable
WHERE Name LIKE 'London,%';
 
-- This will be the MasterID value for the UPDATE - in this example PlaceID=519
PlacesToPlaceDetails-getmasterPlaceID.PNG
Results from 1st query. Choose PlaceID=519 as the master Place.
-- Establish a suitable WHERE constraint that finds all the Places that need to be converted to Place Detail
-- The following worked well. Note the underscore character is a wildcard for any one character and
-- thus precludes a name beginning "London..." from the results.
-- The percent character is a wild card for any number of characters.
 
SELECT * FROM PlaceTable
WHERE Name LIKE '_%London, Ont%' AND PlaceType=0;
 
-- PlaceType of 0=Place, 2=Place Detail (1=Temple)
PlacesToPlaceDetails-testWHEREforPlacesToConvert.PNG
Results from 2nd query showing the Places to be converted to Place Details.
-- Use that WHERE constraint in the following
-- Convert Places in PlaceTable to Place Details of the Master Place (PlaceID=519 in this example)
 
UPDATE PlaceTable SET PlaceType=2, MasterID=519
WHERE Name LIKE '_%London, Ont%' AND PlaceType=0;

SQLite manager reports 4 records updated.

-- Convert Place and Place Detail cited in the EventTable
 
UPDATE EventTable SET SiteID=PlaceID, PlaceID=519
WHERE PlaceID IN
(
 SELECT PlaceID FROM PlaceTable
 WHERE Name LIKE '_%London, Ont%' AND PlaceType=2
 )
AND SiteID=0;

SQLite manager reports 5 records updated, i.e., five events used at least some of the four Places previously converted to Place Details and now use the master Place and the corresponding converted Place Details.

Now look up the Master Place (London, Ontario, Canada) in the RM4 Place List to confirm that the former Places are now its Place Details.

PlacesToPlaceDetails-RMPlaceListResults.PNG
Place List immediately after SQLite queries. 90 Albert was already a Detail for the master Place.
  1. Optionally merge variants of the same place with the target master Place.
  2. Print > Place List > all events in a single place (our “London, Middlesex…” master), check the box “Print place details”.
  3. Inspect the report for unused Place Details and delete them at your discretion.
  4. You may have variants of the same Place Detail that you want to unify; can be done with further queries but for a few, just go to Edit Person and revise the fact. Reiterate from step 2.
  5. Edit each remaining Place Detail to remove the now redundant Master Place info (i.e.”, London, Ont…”)
PlacesToPlaceDetails-RMPlaceListFinal.PNG
Final Place List after bulk SQLite conversions and RM4 edits.

Editing the Place Detail name in RootsMagic 4 rather than in SQLite is necessary because of the proprietary RMNOCASE collation sequence. It is possible to edit the Place Detail name of a RootsMagic 5 database with SQLiteSpy + the fake RMNOCASE extension and then use RM5’s File > Database tools > Rebuild indexes function to correct probable index errors.

Convert Place + Place Detail to Place

This is a much easier, global procedure but needs a SQLite manager that supports a fake RMNOCASE collation, such as SQLiteSpy with the fake RMNOCASE extension (see RMNOCASE – faking it in SQLiteSpy) or SQLite Expert (see RMNOCASE – faking it in SQLite Expert…).

Place_Details-Convert_to_Place.sql
Download this file and load it into SQLiteSpy, having opened your database with it first. Of course, you’ve made a backup! Run the script. The results should be a series of UPDATE statements. Copy these results into a new SQL page in the SQL editor, delete the first line which has the column heading ‘Statement’ and execute all the statements. Place Details are now Places.

You may think you are finished, but not quite. In RM5, do File > Database > Integrity Check. If you see errors reported, then choose Reindex from the same menu and that should clear them. Unfortunately for RM4 users, there is no equivalent tool so you are at greater risk of some form of index corruption due to the fake collation.

/* Place_Details-Convert_to_Place.sql
Converts Place Details + Places into Places; preserves apostrophes
 through some tricky substitutions but other characters may be problematic.
2012-01-22 ve3meo
 
Three steps:
1. Update EventTable SET PlaceID=SiteID, SiteID=0 WHERE SiteID>0
2. Auto generate a statement for each Place Detail of the form
    Update PlaceTable SET Name = SiteName, PlaceName, PlaceType = 0, MasterID = 0
3. Manually copy the resulting series of Update Statements to a SQLite editor and run them
*/
-- Step 1 Open database and run this script
UPDATE EventTable SET PlaceID=SiteID, SiteID=0 WHERE SiteID>0
;
-- Step 2 auatically generates the UPDATE statements for each Place Detail
SELECT 'UPDATE PlaceTable SET Name = '''
       || REPLACE(Site.Name || ', ' || Place.Name, '''', '''''') || ''''       || ', PlaceType = 0, MasterID = 0
       WHERE PlaceID = ' || Site.PlaceID || ';'
       AS Statement
FROM PlaceTable AS Site INNER JOIN PlaceTable AS Place ON Site.MasterID = Place.PlaceID
;
-- Step 3 Copy the resulting UPDATE statements to your SQLite Editor and run them against the database

Discussions & comments from Wikispaces site


mfseeker

Place details to place names conversion

mfseeker
23 January 2012 02:04:56

I need to opposite conversion. I have a couple of hundred place details in my RM5 tree, and I need to export it to be imported into FTM2012. Family Tree Maker does not recognize the place detail tags (ADDR line following a PLAC line). It just ignore the place detail. Is moving the place detail to the first of five places in the place name trivial or difficult. In either case, can someone help me to do it?


ve3meo

ve3meo
23 January 2012 02:38:20

It should be an easier conversion than the opposite. I’m sure somebody will come up with a solution in a few days. Another export issue is shared facts, not covered by standard GEDCOM.